package com.zhss.dfs.upgrade;

import com.sun.xml.internal.bind.v2.model.core.EnumLeafInfo;
import com.zhss.dfs.server.DataNodeConfig;
import com.zhss.dfs.server.NameNodeServiceActor;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.util.concurrent.TimeUnit;

/**
 * @description: 负责执行磁盘的io线程
 * @Author liu Weidong
 * @Email:
 * @Date: 2024/6/2 14:23
 * @Version 1.0
 */
public class IOThread extends Thread{

    public static final Integer READ_TYPE = 1;
    public static final Integer SEND_TYPE = 2;

    private NetworkRequestQueue networkRequestQueue = NetworkRequestQueue.get();

    private NameNodeServiceActor nameNodeServiceActor;

    public IOThread(NameNodeServiceActor nameNodeServiceActor) {
        this.nameNodeServiceActor = nameNodeServiceActor;
    }

    @Override
    public void run() {
        while (true) {
            try {
                NetworkRequest request = networkRequestQueue.poll();
                if (request == null) {
                    TimeUnit.MILLISECONDS.sleep(100);
                    continue;
                }
                Integer requestType = request.getType();
                if (requestType.equals(SEND_TYPE)) {
                    // 上传文件
                    writeFileToDisk(request);
                } else if (requestType.equals(READ_TYPE)) {
                    // 下载文件
                    readFileToDisk(request);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void readFileToDisk(NetworkRequest request) throws IOException {
        FileInputStream inputStream = null;
        FileChannel inputStreamChannel = null;
        try {
            inputStream = new FileInputStream(request.getFileName().getAbsoluteFileName());
            inputStreamChannel = inputStream.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(8 + Long.valueOf(inputStreamChannel.size()).intValue());
            Long fileLength = inputStreamChannel.size();
            buffer.putLong(fileLength);
            int hasReadImageLength = inputStreamChannel.read(buffer);
            System.out.println("从本次磁盘文件中读取了" + hasReadImageLength + " bytes的数据");
            buffer.rewind();
            // 封装请求
            NetworkResponse networkResponse = new NetworkResponse();
            networkResponse.setBuffer(buffer);
            networkResponse.setClient(request.getClient());
            // 放到相应的全局队列
            NetworkResponseQueue.get().offer(request.getProcessorId(),networkResponse);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStreamChannel != null) {
                inputStreamChannel.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    private void writeFileToDisk(NetworkRequest request) throws IOException {
        FileOutputStream outputStream = null;
        FileChannel fileChannel = null;
        try {
            System.out.println("上传的文件的绝对路径为：" + request.getFileName().getAbsoluteFileName());
            outputStream = new FileOutputStream(request.getFileName().getAbsoluteFileName());
            fileChannel = outputStream.getChannel();
            fileChannel.position(fileChannel.size());
            int write = fileChannel.write(request.getFile());
            System.out.println("本次文件上传完毕，将" + write + "字节数据写入到了磁盘...............");
            // 进行上报
            //nameNodeServiceActor.InformReceivedReplicateInfo(request.getFileName().getAbsoluteFileName(),
            //        DataNodeConfig.DATANODE_HOSTNAME, DataNodeConfig.DATANODE_IP,
            //        request.getFileLength());
            System.out.println("项nameNode节点增量汇报完毕。。。。。。。。。");
            // 封装相应
            NetworkResponse networkResponse = new NetworkResponse();
            networkResponse.setClient(request.getClient());
            networkResponse.setBuffer(ByteBuffer.wrap("SUCCESS".getBytes()));
            // 放入到全局响应队列中
            NetworkResponseQueue.get().offer(request.getProcessorId(),networkResponse);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileChannel != null) {
                fileChannel.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }


    }
}
